﻿#ifndef _VIRTUAL_UART_H_
#define _VIRTUAL_UART_H_

#ifdef __cplusplus
extern "C" {
#endif

#include "stdint.h"

#include "main.h"
//#include "stdbool.h"
// #include "typedef.h"
#define TX_BUFF_SIZE 	 255			  	// 设置发送缓冲区的大小
#define VIRTUAL_TX_SLEEP (1)	  		  	// 是否使能主动休眠，降低CPU占用率，但数据吞吐能力会下降	

typedef enum
{
	VIRTUAL_UART_PARITY_DISABLE, /*!< 关闭奇偶校验*/
	VIRTUAL_UART_PARITY_EVEN,	 /*!< 使能偶校验*/
	VIRTUAL_UART_PARITY_ODD,	 /*!< 使能奇校验*/
} virtual_uart_parity_t;

typedef struct
{
	uint16_t head;
	uint16_t tail;
	uint16_t len;
	uint8_t tx_buff[TX_BUFF_SIZE];
} virtual_tx_ring_buff_t;  /*发送环形缓冲区*/

typedef struct
{
	uint8_t send_temp;
	uint8_t send_cnt;
} virtual_tx_transaction_t;/*发送事务执行进度缓冲*/

typedef struct 
{
	virtual_uart_parity_t PARITY;
}virtual_uart_config_t;

/**
 * @brief 拉高IO口回调函数原型
 */
typedef void (*virtual_uart_set_io_cb_t)(void);
/**
 * @brief 拉低IO口回调函数原型
 */
typedef void (*virtual_uart_reset_io_cb_t)(void);
/**
 * @brief 进入临界区回调函数原型
 * @note 一般实现为关闭定时器中断
 */
typedef void (*virtual_uart_ENTER_CRITICAL_cb_t)(void);
/**
 * @brief 进入临界区回调函数原型
 * @note 一般实现为开启定时器中断
 */
typedef void (*virtual_uart_EXIT_CRITICAL_cb_t)(void);
/**
 * @brief 重启定时器并重新开启中断
 * @note VIRTUAL_TX_SLEEP为1时必须实现
 */
typedef void (*virtual_uart_restart_cb_t)(void);
/**
 * @brief 关闭定时器并关闭定时器中断，且必须清除定时器计数
 * @note VIRTUAL_TX_SLEEP为1时必须实现
 */
typedef void (*virtual_uart_sleep_cb_t)(void);

typedef struct
{
	/**
	 * @note 下方4个回调必须全部实现
	 */
	virtual_uart_set_io_cb_t set_io;				 // 外部实现一个拉高IO口的回调函数并注册到这里
	virtual_uart_reset_io_cb_t reset_io;			 // 外部实现一个拉低IO口的回调函数并注册到这里
	virtual_uart_ENTER_CRITICAL_cb_t ENTER_CRITICAL; // 外部实现一个关闭定时器中断的回调函数并注册到这里
	virtual_uart_EXIT_CRITICAL_cb_t EXIT_CRITICAL;	 // 外部实现一个开启定时器中断的回调函数并注册到这里
#if VIRTUAL_TX_SLEEP
	virtual_uart_restart_cb_t virtual_uart_restart; // 外部实现一个开启定时器中断、重启并清空定时器计数的回调函数并注册到这里
	virtual_uart_sleep_cb_t virtual_uart_sleep;		// 外部实现一个关闭定时器中断并使定时器休眠的回调函数并注册到这里
	bool is_sleep;									// 指示模拟串口是否已经休眠
#endif
	virtual_tx_ring_buff_t virtual_tx_buff;	 // 一个发送环形队列
	virtual_tx_transaction_t tx_transaction; // 发送事务
	virtual_uart_config_t virtual_uart_config;//
} virtual_uart_t;
/**
 * @brief 虚拟串口写入
 *
 * @param virtual_uart_handler 模拟串口句柄
 *
 * @return int
 * @retval  0 ： 正常发送
 * @retval -1 ： 发送队列满，需要确定是否短时调用次数超过缓冲能力，修改TX_BUFF_SIZE可以缓解
 */
int virtual_uart_tx_buff_write(virtual_uart_t *virtual_uart_handler, uint8_t dat);
/**
 * @brief 循环调用的模拟串口心跳，需要根据波特率周期性调用。
 *
 * @note 比如19200需要52微秒调用一次
 *
 * @param virtual_uart_handler 模拟串口句柄
 *
 * @return void 保留
 */
void virtual_uart_loop(virtual_uart_t *virtual_uart_handler);

#ifdef __cplusplus
}
#endif

#endif /* _VIRTUAL_UART_H_ */
